package com.rp.data.tcp_ws.server_tcp;
import com.alibaba.druid.util.HexBin;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rp.common.config.redis.RedisUtil;
import com.rp.common.utils.NullIs;
import com.rp.common.utils.SpringContextUtils;

import com.rp.configure.entity.Gateway;
import com.rp.configure.service.DeviceAttributeService;
import com.rp.configure.service.GatewayService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
//接受网关数据
public class ServerHandlerTcp extends SimpleChannelInboundHandler<String> {
    // 所有的活动用户
    private static RedisUtil redisUtil = (RedisUtil) SpringContextUtils.getBean(RedisUtil.class);
    private static GatewayService gatewayService = (GatewayService) SpringContextUtils.getBean(GatewayService.class);
    private static DeviceAttributeService deviceAttributeService = (DeviceAttributeService) SpringContextUtils.getBean(DeviceAttributeService.class);
    public static final ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    public static Map<String,Channel> channelMap = new HashMap<>();
    public static Map<Channel,String> mapChannel = new HashMap<>();

    // 读取消息通道
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {

        log.info("收到到的消息有" + msg);
        if (mapChannel.get(ctx.channel()).equals("0222")) {
            QueryWrapper<Gateway> wrapper = new QueryWrapper<>();
            wrapper.eq("sn", msg);
            log.info("读到的消息有" + msg);
            Gateway gateway = gatewayService.getOne(wrapper);
            if (!NullIs.isEmpty(gateway)) {
                String[] split = ctx.channel().remoteAddress().toString().replace("/", "").split(":");
                gateway.setIp(split[0]);
                gateway.setPort(split[1]);
                if (gateway.getIsOnline()==0){
                    gateway.setIsOnline(1);
                }
                gatewayService.updateById(gateway);

                mapChannel.put(ctx.channel(), gateway.getId());
            }
        } else {
            Boolean key = redisUtil.hasKey(String.valueOf(ctx.channel().hashCode()));
            if (key) {
                redisUtil.setEx(String.valueOf(ctx.channel().hashCode()), msg, 600, TimeUnit.MILLISECONDS);
            }
            byte[] bytes = HexBin.decode(msg.replace(" ", ""));
            if (bytes.length > 4) {
                log.info("执行消息处理"+mapChannel.get(ctx.channel()));
                deviceAttributeService.handleMessage(mapChannel.get(ctx.channel()),bytes);
                }
//            System.out.println("发送关灯数据"+"020F0000000201009E82");
//            ctx.channel().writeAndFlush("020F0000000201009E82");

//                System.out.println("发送开灯数据" + "020F0000000201FFDEC2");
//                ctx.channel().writeAndFlush("020F0000000201FFDEC2");
            }
        }


    // 处理新加的消息通道
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            //根据ip和端口查询数据库来进行判断是哪一个类型的网关
//        String[] split = ctx.channel().remoteAddress().toString().replace("/", "").split(":");
//        switch (split[0]){
//            case "1":break;
//        }
            //0222网关发送后返回sn号用于唯一标识
        Channel channel = ctx.channel();
        channel.writeAndFlush("FE0403EE000885B2");
        mapChannel.put(channel,"0222");

        group.add(channel);
        }


    // 处理退出消息通道
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();


        mapChannel.remove(channel);
        group.remove(channel);
    }

    // 在建立连接时发送消息
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        boolean active = channel.isActive();
    }


    // 退出时发送消息
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
    }

    // 异常捕获
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {
        e.printStackTrace();
        Channel channel = ctx.channel();
        ctx.close().sync();
    }
}
